fn bisection(f: &dyn Fn(f64) -> f64, interval: (f64, f64), tol: f64) -> (f64, i32) {
    let (mut a, mut b) = interval;
    let mut fa = f(a);
    let fb = f(b);
    if a >= b || fa * fb >= 0. || tol <= 0. {
        return (f64::NAN, -1);
    }

    let n_max = ((b - a).log2() - (2. * tol).log2()).ceil() as i32;
    for i in 1..n_max + 1 {
        let p = (a + b) / 2.;
        let fp = f(p);
        if fp.abs() <= f64::EPSILON {
            return (p, i);
        } else if fa * fp < 0. {
            b = p;
            // fb = fp;
        } else {
            a = p;
            fa = fp;
        }
    }
    ((a + b) / 2., n_max)
}

fn fex3(x: f64) -> f64 {
    x * x * x - 30. * x * x + 2552.
}

fn main() {
    let (p, n) = bisection(&fex3, (0., 20.), 1e-8);
    println!("p = {}, n = {}", p, n);
}
